import lombok.extern.slf4j.Slf4j;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.*;

public class ServerPoint {
    public static Executor acceptpool = Executors.newFixedThreadPool(2);
    public static BlockingQueue<Common.RequestC> queue = new LinkedBlockingQueue(16);
    public static Executor handlepool = Executors.newFixedThreadPool(2);
    interface Controller{
        void doit(Common.RequestC req, Common.ResponseC res);
    }
    public static ConcurrentHashMap<String,Controller> controllers=
            new ConcurrentHashMap<>(5);
    public static void main(String[] args) throws IOException {
        Common common = new Common();
        controllers.put("save",((req, res) -> {
            System.out.println(req);
            res.setBody("Saving!!!"+req.getBody());
            res.setStatus("200");
        }));
        controllers.put("error",((req, res) -> {
            System.out.println(req);
            res.setStatus("404");
            res.setBody("not found!!!" +req.getUrl_head());
        }));

        new Thread(()->{
           while (true){
               Common.debug("handle engine");
               try {
                   Common.RequestC requestC = queue.take();
                    handlepool.execute(()->{
                        Common.debug("handle request like :");
                        Common.debug(requestC);
                        if (controllers.containsKey(requestC.getUrl_head())){
                            Controller controller = controllers.get(requestC.getUrl_head());
                            controller.doit(requestC,requestC.responseC);
                        }
                        else {
                            controllers.get("error").doit(requestC,requestC.responseC);
                        }

                        try {
                            requestC.responseC.dataOutputStream.writeUTF(requestC.responseC.toTransString());
                            requestC.responseC.dataOutputStream.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                    });

               } catch (InterruptedException e) {
                   e.printStackTrace();
               }


           }
        }).start();
        ServerSocket serverSocket = new ServerSocket(7766);
        while (true){

            Socket socket = serverSocket.accept();
            System.out.println("got one request");
            acceptpool.execute(()->{
                try {
                    DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
                    String s = dataInputStream.readUTF();
                    Common.debug(s);
                    Common.RequestC requestC = common.parseReq(s);
                    requestC.responseC.dataOutputStream=new DataOutputStream(socket.getOutputStream());
                    Common.debug(requestC.toTransString());
                    queue.put(requestC);
                }catch (Exception e){
                    System.out.println(e.getMessage());
                }
            });

        }


    }

}
